#!/usr/bin/env python
# coding=UTF-8
import random
import logging
import json
import time
import datetime
import copy

import config
import dao

from nsq.http import nsqd
import redisco
from redisco.containers import List, Hash
import itertools

def json_encode(data):
    return json.dumps(data, separators=(',', ':'))

def nsq_pub(message, topic='response'):
    try:
        nsq_client = nsqd.Client("http://%s/" % config.NSQ_HTTP)
        if isinstance(message, dict):
            message = json_encode(message)
        logging.info(u"推送消息:%s" % message)
        nsq_client.pub(topic, message)
        return True
    except:
        logging.error("nsq send error", exc_info=True)
        return False

def get_last_data(reader, bid, uid, data):
    uid = str(uid)
    user_info = Hash("%s_%s" % (bid, uid))
    rid = user_info['rid']
    if not rid:
        rid = data.get("rid", "")
    room = Hash("r:%s" % rid)
    tdh = PaoHuZi(rid, bid)
    last_get_user = tdh.room['last_get_user']
    last_put_user = tdh.room['last_put_user']
    last_card_type = tdh.room['last_card_type']
    last_card = tdh.room['last_card']
    if not last_card:
        last_card = ""
        last_card_uid = ""
        last_card_type = ""
    else:
        if last_card_type == 'put':
            last_card_uid = last_put_user
        elif last_card_type == 'get':
            last_card_uid = last_get_user
        else:
            last_card_uid = ""
    all_player_data = []
    l = List("r:%s:p" % rid)
    members = l.members
    for member in members:
        p = Player(member, bid, rid)
        player_data = p.get_data()
        eat_list = []
        eat_data_list = player_data['eat']
        for eat_data in eat_data_list:
            eat_list.append(eat_data.split(","))
        player_data['eat'] = eat_list
        if member != uid:
            player_data['current_card'] = []
            player_data['lock_card'] = []
        else:
            current_user_card, lock_card = tdh.card_sort(player_data['current_card'])
            player_data['current_card'] = current_user_card
            player_data['lock_card'] = lock_card
        player_data['status'] = 1
        if player_data['bind']:
            bind_data = []
            for bind in player_data['bind']:
                bind_data.append([bind]*4)
            player_data['bind'] = bind_data
        if player_data['run']:
            run_data = []
            for run in player_data['run']:
                run_data.append([run]*4)
            player_data['run'] = run_data
        if player_data['nestle']:
            nestle_data = []
            for nestle in player_data['nestle']:
                nestle_data.append([nestle]*3)
            player_data['nestle'] = nestle_data
        
        if player_data['pair']:
            pair_data = []
            for pair in player_data['pair']:
                pair_data.append([pair]*3)
            player_data['pair'] = pair_data
            
        all_player_data.append(player_data)
    left_card = len(tdh.current_card.members)
    dealer = tdh.room['dealer']
    if not dealer:
        dealer = ''
        
    data = {"act":"get_last_data", 
            "last_card_type":last_card_type, 
            "last_card_uid":last_card_uid, 
            "last_card":last_card, 
            "left_card":left_card,
            "game_round":room['game_round'],
            "all_round":room['all_round'],
            "dealer":dealer,
            "all_player_data":all_player_data,
            "rid":rid,
           }
    
    nsq_pub({"b":bid, "u":uid, "t":"game", "d":data})
    
    if uid in tdh.tips_user:
        p = Player(uid, bid, rid)
        tips = p.tips.members
        tips = list(set(tips))
        if tips:
            display_card = {}
            need_display = "n"
            eat_card = []
            current_card = p.current_card.members
            if "eat" in tips:
                eat_card, display_card, need_display = tdh.check_eat(current_card, last_card)
            nsq_pub({"b":bid, "u":uid, "t":"game", "d":{"act":"tips", "tips":tips, "card":last_card, "eat_card":eat_card, "display_card":display_card, "need_display":need_display}})
    else: 
        turn_put_uid = tdh.room['turn_put']
        if turn_put_uid:
            tdh.notify_put(turn_put_uid)
            #nsq_pub({"b":bid, "u":str(uid), "t":"game", "d":{"act":"turn_put", "rid":rid, "uid":tdh.room['turn_put']}})
        
        
class Player():
    def __init__(self, uid, bid='', rid='', first=False):
        self.uid = uid
        self.bid = bid
        if first:
            redisco.connection.delete("p:%s:%s:%s:current_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:out_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:bind" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:run" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:pair" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:eat" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:nestle" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:bad_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:eat_bad_card" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s:tips" % (bid, uid, rid))
            redisco.connection.delete("p:%s:%s:%s" % (bid, uid, rid))
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
            self.score['score'] = 0
            self.score['win_score'] = 0
            self.score['huxi'] = 0
            #违规
            #self.score['flag'] = ''
            self.score['win_from'] = ''
            #冲招后不能吃碰
            self.score['chongzhao'] = ''
        else:
            self.score = Hash("p:%s:%s:%s" % (bid, uid, rid))
        self.current_card = List("p:%s:%s:%s:current_card" % (bid, uid, rid))
        self.out_card = List("p:%s:%s:%s:out_card" % (bid, uid, rid))
        self.bind = List("p:%s:%s:%s:bind" % (bid, uid, rid))
        self.run = List("p:%s:%s:%s:run" % (bid, uid, rid))
        self.pair = List("p:%s:%s:%s:pair" % (bid, uid, rid))
        self.eat = List("p:%s:%s:%s:eat" % (bid, uid, rid))
        #偎牌
        self.nestle = List("p:%s:%s:%s:nestle" % (bid, uid, rid))
        #过张臭牌
        self.bad_card = List("p:%s:%s:%s:bad_card" % (bid, uid, rid))
        self.eat_bad_card = List("p:%s:%s:%s:eat_bad_card" % (bid, uid, rid))
        self.tips = List("p:%s:%s:%s:tips" % (bid, uid, rid))

    def get_data(self):
        return {"uid":self.uid,
                "current_card":self.current_card.members,
                "out_card":self.out_card.members,
                "bind":self.bind.members,
                "run":self.run.members,
                "pair":self.pair.members,
                "eat":self.eat.members,
                "nestle":self.nestle.members,
                "score":self.score['score'],
                "huxi":self.score['huxi'],
                }
        
  
class PaoHuZi():
    def __init__(self, rid, bid, dealer=None):
        self.rid = str(rid)
        if dealer:
            redisco.connection.delete("r:%s:current_card" % rid)
            redisco.connection.delete("r:%s:out_card" % rid)
            redisco.connection.delete("r:%s:mid" % rid)
            redisco.connection.delete("r:%s:tips_user" % rid)
            redisco.connection.delete("r:%s:tips_act" % rid)
            self.room = Hash("r:%s" % rid)
            self.room['dealer'] = dealer
            self.room['last_get_user'] = dealer
            self.room['last_put_user'] = ''
            self.room['stop_pop_user'] = ''
            self.room['stop_pop_act'] = ''
            self.room['last_get_card'] = ''
            self.room['last_card'] = ''
        else:
            self.room = Hash("r:%s" % rid)
        self.current_card = List("r:%s:current_card" % rid)
        self.out_card = List("r:%s:out_card" % rid)
        self.bid = bid
        l = List("r:%s:p" % rid)
        self.members = l.members
        self.tips_user = List("r:%s:tips_user" % rid)
        self.tips_act = List("r:%s:tips_act" % rid)
        self._res = []
        
    def incr_mid(self):
        return redisco.connection.incr("r:%s:mid" % self.rid)
    
    def trans_card(self, all_card):
        res = [int(x) for x in all_card]
        res.sort()
        return res
    
    def valid_card_num(self, card_list):
        bomb = self.get_bomb(card_list)
        nestle = self.get_nestle(card_list)
        return len(card_list) - len(bomb)*4 - len(nestle)*3
        
    def format_card(self, player, card, jiang='', win_from='', win_type=''):
        res = []
        bind = player.bind.members
        run = player.run.members
        nestle = player.nestle.members
        pair = player.pair.members
        eat = player.eat.members
        current_card = player.current_card.members
        for c in bind:
            if win_from == 'bind' and str(card) == c:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"bind","cc":[c]*4, "in_flag":in_flag})
        for c in run:
            if win_from == 'run' and str(card) == c:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"run","cc":[c]*4, "in_flag":in_flag})
        for c in nestle:
            if win_from == 'nestle' and str(card) == c:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"nestle","cc":[c]*3, "in_flag":in_flag})
        
        for ec in eat:
            cc = ec.split(",")
            if win_from == 'eat' and str(card)in cc:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"eat","cc":cc, "in_flag":in_flag})
        group_n, bomb, triple, pair_card, seq, jiang, left_card = self.count_group(current_card, card, jiang)
        pair.extend(pair_card)
        if card and win_type != "win":
            for tp in set(triple):
                if str(tp) == str(card):
                    triple.remove(tp)
                    pair.append(str(card))
            
        logging.info(u"===bomb:%s,tiple:%s,seq:%s,jiang:%s,left:%s" % (str(bomb), str(triple), str(seq), jiang, str(left_card)))
        
        for c in pair:
            if str(card) == c:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"pair","cc":[c]*3, "in_flag":in_flag})
            
        if jiang:
            if str(card) == str(jiang):
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"jiang","cc":[str(jiang)]*2, "in_flag":in_flag})
        
        for c in bomb:
            res.append({"tp":"bind","cc":[str(c)]*4, "in_flag":"n"})
        for c in triple:
            if str(card) == str(c):
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"triple","cc":[str(c)]*3, "in_flag":in_flag})
        for ss in seq:
            cc = [str(x) for x in ss]
            if not win_from and str(card) in cc:
                in_flag = 'y'
            else:
                in_flag = 'n'
            res.append({"tp":"seq","cc":cc, "in_flag":in_flag})
        for i in range(0, len(left_card), 4):
            cc = left_card[i:i+4]
            res.append({"tp":"","cc":[str(x) for x in cc], "in_flag":"n"})
        return res
    
    def card_sort(self, all_card):
        res = []
        #card_list = sorted(card_list, key=lambda x:int(x))
        card_list = [int(x) for x in all_card]
        card_list.sort()
        bomb = []
        triple = []
        pair = []
        for c in card_list:
            c_cnt = card_list.count(c)
            if c_cnt == 4:
                bomb.append([c]*c_cnt)
                for i in range(c_cnt):
                    card_list.remove(c)
            elif c_cnt == 3:
                triple.append([c]*c_cnt)
                for i in range(c_cnt):
                    card_list.remove(c)
        while card_list:
            c = card_list.pop(0)
            c_cnt = card_list.count(c)
            if c == 101:
                s2 = 102
                s3 = 103
                if s2 in card_list and s3 in card_list:
                    res.append([c,s2,s3])
                    card_list.remove(s2)
                    card_list.remove(s3)
                    continue
                elif c_cnt == 1:
                    pair.append([c, c])
                    card_list.remove(c)
                    continue
            elif c == 102:
                s7 = 107
                s10 = 110
                if s7 in card_list and s10 in card_list:
                    res.append([c,s7,s10])
                    card_list.remove(s7)
                    card_list.remove(s10)
                    continue
                elif c_cnt == 1:
                    pair.append([c, c])
                    card_list.remove(c)
                    continue
            elif c == 201:
                b2 = 202
                b3 = 203
                if b2 in card_list and b3 in card_list:
                    res.append([c,b2,b3])
                    card_list.remove(b2)
                    card_list.remove(b3)
                    continue
                elif c_cnt == 1:
                    pair.append([c, c])
                    card_list.remove(c)
                    continue
            elif c == 202:
                b7 = 207
                b10 = 210
                if b7 in card_list and b10 in card_list:
                    res.append([c,b7,b10])
                    card_list.remove(b7)
                    card_list.remove(b10)
                    continue
                elif c_cnt == 1:
                    pair.append([c, c])
                    card_list.remove(c)
                    continue
            elif c_cnt == 1:
                if c > 200:
                    c_other = c-100
                else:
                    c_other = c + 100
                if c_other in card_list and card_list.count(c_other) == 1:
                    res.append([c, c, c_other])
                    card_list.remove(c_other)
                else:
                    pair.append([c, c])
                card_list.remove(c)
                continue
            else:
                c1 = c+1
                c2 = c+2
                if c1 in card_list and c2 in card_list:
                    res.append([c, c1, c2])
                    card_list.remove(c1)
                    card_list.remove(c2)
                    continue
                elif c1 in card_list:
                    res.append([c, c1])
                    card_list.remove(c1)
                    continue
            res.append([c])
        
        tmp_list = []
        for t in bomb:
            tmp_list.append(t)
        for t in triple:
            tmp_list.append(t)
        for p in pair:
            tmp_list.append(p)
        res = sorted(res, key=lambda x:len(x), reverse=True)
        for r in res:
            tmp_list.append(r)
        if len(tmp_list) > 12:
            i = 11
            for c in tmp_list[12:]:
                tmp_list[i].extend(c)
                i -= 1
        result = []
        for m in tmp_list:
            result.append([str(x) for x in m])
        lock_card = []
        for bb in bomb:
            for b in set(bb):
                lock_card.append(str(b))
        for tt in triple:
            for t in set(tt):
                lock_card.append(str(t))
        return result, lock_card

    def is_wuhu(self, card_list):
        '''乌胡,100分'''
        logging.info(u"检查是否是乌胡:%s" % str(card_list))
        all_card = self.trans_card(card_list)
        for c in all_card:
            if c in (102, 107, 110, 202, 207, 210):
                return False
        return 'wuhu'
    
    def is_honghu(self, card_list):
        '''只有一个红字, 加一番, 十三红100分, 10红加一番'''
        logging.info(u"检查是否是红胡:%s" % str(card_list))
        n = 0
        all_card = self.trans_card(card_list)
        for c in all_card:
            if c in (102, 107, 110, 202, 207, 210):
                n += 1
        if n == 1:
            return 'yidianhong'
        elif n >= 13:
            return 'shisanhong'
        elif n >= 10:
            return 'shihong'
        return False
    
    def is_yikuaibian(self, all_card):
        '''一块匾, 加一番'''
        logging.info(u"检查是否一块匾:%s" % str(all_card))
        n = 0
        #if [101,102,103] in all_card or [201,202,203] in all_card or [102,103,104] in all_card or [202,203,204] in all_card or [105,106,107] in all_card or [205,206,207] in all_card or [106,107,108] in all_card or [206,207,208] in all_card or [107,108,109] in all_card or [207,208,209] in all_card or [108,109,110] in all_card or [208,209,210] in all_card:
        #    return False
        for group in all_card:
            if group in ([101,102,103],[102,103,104],[105,106,107],[106,107,108],[107,108,109],[108,109,110],[201,202,203],[202,203,204],[205,206,207],[206,207,208],[207,208,209],[208,209,210],):
                return False
            if group in ([102,107,110],[202,207,210],[102,202,202],[102,102,202],[107,107,207],[107,207,207],[110,110,210],[110,210,210]):
                n += 1
        for c in (102,107,110,202,207,210):
            if [c]*4 in all_card:
                n += 1
            elif [c]*3 in all_card:
                n += 1
            elif [c]*2 in all_card:
                n += 1
        if n == 1:
            return 'yikuaibian'
        return False

    def trans_mingtang(self, mingtang):
        res = []
        conf = {'tianhu':u"天胡", 'dihu':u"地胡", 'zimohu':u"自摸胡", 
                'yidianhong':u"一点红", 'wuhu':u"乌胡", 'yikuaibian':u"一块匾",
                'shihong':u"十红", 'shisanhong':u"十三红", 
                'kahu30':u"卡胡", 'kahu20':u"卡胡", 'haidihu':u"海底胡", 'put_win':u"点炮胡"}
        for m in mingtang:
            res.append(conf[m])
        return " ".join(res)
            
    def get_mingtang(self, player, card='', win_score=0, win_type=''):
        logging.info(u"跑胡子%s玩家胡牌,检查名堂%s, card:%s, win_score:%s" % (self.rid, player.uid, card, win_score))
        n = 0
        res = []
        bind = [int(x) for x in player.bind.members]
        run = [int(x) for x in player.run.members]
        pair = [int(x) for x in player.pair.members]
        nestle = [int(x) for x in player.nestle.members]
        eat = player.eat.members
        n += len(bind)
        n += len(run)
        n += len(pair)
        n += len(nestle)
        n += len(eat)
        current_card = player.current_card.members
        bomb = self.get_bomb(current_card)
        #if card:
        #    current_card.append(card)
        eat_list = []
        card_list = []
        for b in bind:
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
        for b in run:
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
        for b in pair:
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
        for b in nestle:
            card_list.append(b)
            card_list.append(b)
            card_list.append(b)
        card_list.extend(current_card)
        for cc in eat:
            c = cc.split(",")
            c.sort()
            card_list.extend(c)
            eat_list.append(c)
        
        wuhu = self.is_wuhu(card_list)
        if wuhu:
            res.append(wuhu)
        
        honghu = self.is_honghu(card_list)
        if honghu:
            res.append(honghu)
            
        if win_score == 30:
            res.append("kahu30")
        elif win_score == 20:
            res.append("kahu20")
        if not self.current_card:
            res.append("haidihu")
        if win_type == "put_win":
            res.append("put_win")
            if len(self.current_card) == 19 and len(self.out_card.members) == 1:
                res.append("dihu")
        elif win_type == "win":
            res.append("zimohu")
            if len(self.current_card) == 19 and len(self.out_card.members) == 0:
                res.append("tianhu")
        if len(bind)+len(run)+len(bomb) >= 1:
            jiang_list = self.get_jiang(current_card, card)
            if not jiang_list:
                return []
            for jiang in jiang_list:
                group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(current_card, card, jiang)
                if not left_card and group_n + n >= 7:
                    break
        else:
            group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(current_card, card, '')
        all_sort_card = []
        for b in bind:
            all_sort_card.append([b]*4)
        for b in run:
            all_sort_card.append([b]*4)
        for b in pair:
            all_sort_card.append([b]*3)
        for b in nestle:
            all_sort_card.append([b]*3)
        for b in bomb_card:
            all_sort_card.append([b]*4)
        for b in triple:
            all_sort_card.append([b]*3)
        for b in pair_card:
            all_sort_card.append([b]*3)
        for b in seq:
            all_sort_card.append(b)
        if jiang_pai:
            all_sort_card.append([jiang_pai]*2)
        for cc in eat:
            ec = [int(x) for x in cc.split(",")]
            ec.sort()
            all_sort_card.append(ec)
            
        yikuaibian = self.is_yikuaibian(all_sort_card)
        if yikuaibian:
            res.append(yikuaibian)
        
        return res
        
    def count_score(self, win_score, mingtang):
        if 'wuhu' in mingtang:
            win_score = 100
        elif 'kahu30' in mingtang:
            win_score = 100
        elif 'tianhu' in mingtang:
            win_score = 100
        elif 'dihu' in mingtang:
            win_score = 100
        elif 'shisanhong' in mingtang:
            win_score = 100
        else:
            if 'yidianhong' in mingtang:
                win_score *= 2
            if 'shihong' in mingtang:
                win_score *= 2
            if 'yikuaibian' in mingtang:
                win_score *= 2
            if 'kahu20' in mingtang:
                win_score *= 2
        if 'zimohu' in mingtang:
            win_score *= 2
        if 'haidihu' in mingtang:
            win_score *= 2
        return win_score
    
    def check_init_bind(self, card_list):
        res = []
        for card in set(card_list):
            if card_list.count(card) == 4:
                res.append(card)
        return res
    
    def check_bind(self, card_list, card):
        if card_list.count(card) == 3:
            return card
        return False
    
    def check_run(self, p, card):
        if card in p.nestle:
            return 'nestle'
        elif card in p.pair:
            return 'pair'
        card_list = p.current_card.members
        if card_list.count(card) == 3:
            return 'run'
        return False
    
    def check_pair(self, card_list, card):
        if card_list.count(card) == 2:
            return card
        return False
    
    def check_nestle(self, card_list, card):
        if card_list.count(card) == 2:
            return card
        return False
    
    def cal_display(self, card_list, eat_card_list, card):
        '''计算比牌/摆火'''
        res = {}
        for eat_card in eat_card_list:
            eat_card.sort()
            key = "%s_%s" % (eat_card[0], eat_card[1])
            res[key] = []
            all_card = [x for x in card_list]
            for c in eat_card:
                all_card.remove(c)
            for ec in eat_card_list:
                if card in ec:
                    if all_card.count(card) == 2 and ec[0] in all_card and ec[1] in all_card:
                        cc = [card, ec[0], ec[1]]
                        cc.sort()
                        res[key].append(cc)
                elif card in all_card and ec[0] in all_card and ec[1] in all_card:
                    cc = [card, ec[0], ec[1]]
                    cc.sort()
                    res[key].append(cc)
        return res
    
    def can_eat(self, eat_card, card):
        card_list = [int(x) for x in eat_card]
        card_list.append(int(card))
        if len(card_list) != 3:
            return False
        
        card_list.sort()
        if card_list[0]+1 == card_list[1] and card_list[0]+2 == card_list[2]:
            return True
        if card_list[0]%100 == card_list[1]%100 and card_list[0]%100 == card_list[2]%100:
            return True
        if card_list in ([102,107,110], [202,207,210]):
            return True
        return False
    
    def check_eat(self, card_list, card):
        all_card = self.trans_card(card_list)
        c = int(card)
        if c in all_card:
            need_display = 'y'
        else:
            need_display = 'n'
        if all_card.count(c) > 2:
            return [], {}, need_display
        color = c / 100
        eat_card = []
        if all_card.count(c-2) in (1,2) and all_card.count(c-1) in (1,2):
            eat_card.append([c-2, c-1])
        if all_card.count(c+1) in (1,2) and all_card.count(c+2) in (1,2):
            eat_card.append([c+1, c+2])
        if all_card.count(c-1) in (1,2) and all_card.count(c+1) in (1,2):
            eat_card.append([c-1, c+1])
        if color == 1:
            if all_card.count(c+100) == 2:
                eat_card.append([c+100, c+100])
            if all_card.count(c+100) in(1,2) and all_card.count(c) in(1,2):
                eat_card.append([c, c+100])
        else:
            if all_card.count(c-100) == 2:
                eat_card.append([c-100, c-100])
            if all_card.count(c-100) in (1,2) and all_card.count(c) in (1,2):
                eat_card.append([c-100, c])
        if c == 102 and all_card.count(107) in (1,2) and all_card.count(110) in (1,2):
            eat_card.append([107, 110])
        elif c == 107 and all_card.count(102) in (1,2) and all_card.count(110) in (1,2):
            eat_card.append([102, 110])
        elif c == 110 and all_card.count(102) in (1,2) and all_card.count(107) in (1,2):
            eat_card.append([102, 107])
        elif c == 202 and all_card.count(207) in (1,2) and all_card.count(210) in (1,2):
            eat_card.append([207, 210])
        elif c == 207 and all_card.count(202) in (1,2) and all_card.count(210) in (1,2):
            eat_card.append([202, 210])
        elif c == 210 and all_card.count(202) in (1,2) and all_card.count(207) in (1,2):
            eat_card.append([202, 207])
        display_res = {}
        eat_card_list = [x for x in eat_card]
        for ec in eat_card_list:
            ec.sort()
            key = "%s_%s" % (ec[0], ec[1])
            e1_cnt = all_card.count(ec[0])
            e2_cnt = all_card.count(ec[1])
            allcard = self.trans_card(card_list)
            for e in ec:
                allcard.remove(e)
            tmp = []
            c_left = allcard.count(c)
            if c_left == 0:
                tmp = [sorted([str(c), str(ec[0]), str(ec[1])])]
                #display_res[key] = [tmp]
                display_res[key] = []
                continue
            
            for cc in eat_card:
                cc.sort()
                if c_left == 2 and allcard.count(cc[0]) == 2 and allcard.count(cc[1]) == 2:
                    ccc = [str(c), str(cc[0]), str(cc[1])]
                    ccc.sort()
                    tmp.append(ccc)
                    tmp.append(ccc)
                elif c in cc:
                    if c_left == 2 and allcard.count(cc[0]) in (1, 2) and allcard.count(cc[1]) in (1, 2):
                        ccc = [str(c), str(cc[0]), str(cc[1])]
                        ccc.sort()
                        tmp.append(ccc)
                elif c_left in (1, 2) and allcard.count(cc[0]) in (1, 2) and allcard.count(cc[1]) in (1, 2):
                    ccc = [str(c), str(cc[0]), str(cc[1])]
                    ccc.sort()
                    tmp.append(ccc)
            tmp_res = []
            if len(tmp) > 1:
                for comb in itertools.combinations(tmp, 2):
                    cb = list(comb)
                    if cb[0].count(str(c)) == c_left:
                        tmp_res.append([cb[0]])
                    if cb[1].count(str(c)) == c_left:
                        tmp_res.append([cb[1]])
                    else:
                        tmp_res.append(cb)
            else:
                if tmp:
                    tmp_res.append(tmp)
            tt_res = []
            for tt in tmp_res:
                k1 = str(ec[0])
                k2 = str(ec[1])
                k1_cnt = 1
                k2_cnt = 1
                c_cnt = 0
                for t in tt:
                    k1_cnt += t.count(k1)
                    k2_cnt += t.count(k2)
                    c_cnt += t.count(str(c))
                if (k1_cnt > e1_cnt or k2_cnt > e2_cnt) or c_cnt < c_left:
                    pass
                else:
                    if tt in tt_res:
                        continue
                    tt_res.append(tt)
            if need_display == 'y' and not tt_res:
                eat_card.remove(ec)
            else:
                display_res[key] = tt_res
        res = []
        if not eat_card:
            display_res = {}
        for ec in eat_card:
            ec.sort()
            res.append([str(x) for x in ec])
        return res, display_res, need_display
    
    def get_jiang(self, all_card, card=''):
        jiang_list = []
        for c in set(all_card):
            if all_card.count(c) == 2:
                jiang_list.append(c)
            elif all_card.count(c) == 3 and str(c) == str(card):
                jiang_list.append(c)
        return [int(x) for x in jiang_list]
    
    def get_bomb(self, all_card):
        res = []
        for c in set(all_card):
            if all_card.count(c) == 4:
                res.append(c)
        return res
    
    def get_nestle(self, all_card):
        res = []
        for c in set(all_card):
            if all_card.count(c) == 3:
                res.append(c)
        return res
    
    def all_group(self, all_card, card):
        c1 =card+1
        c2 =card+2
        if card > 200:
            s1 = card -100 
        else:
            s1 = card + 100
        res = []
        if c1 in all_card and c2 in all_card:
            res.append([c1, c2])
            
        if card == 102:
            c1 = 107
            c2 = 110
        elif card == 202:
            c1 = 207
            c2 = 210
        if c1 in all_card and c2 in all_card:
            res.append([c1, c2])
            
        c_cnt = all_card.count(card)
        s_cnt = all_card.count(s1)
        if c_cnt == 1:
            if s_cnt >1:
                res.append([s1, s1])
                res.append([card, s1])
            elif s_cnt == 1:
                res.append([card, s1])
        else:
            if s_cnt >= 2:
                res.append([s1, s1])
        return res
    
    def card_group(self, all_card, res=''):
        pre = res
        card_list = self.trans_card(all_card)
        if not card_list:
            return ''
        c = card_list.pop(0)
        all_group = self.all_group(card_list, c)
        if not all_group:
            last = self.card_group(card_list, pre)
            return last
        else:
            for group in all_group:
                tmp = pre
                acard = copy.deepcopy(card_list)
                g1 = group[0]
                g2 = group[1]
                acard.remove(g1)
                acard.remove(g2)
                tmp += "%s,%s,%s_" % (c, g1, g2)
                last = self.card_group(acard, tmp)
                self._res.append(tmp)
        return last
    
    def card_group_res(self, all_card):
        card_list = self.trans_card(all_card)
        tmp_result = []
        for group in self._res:
            if group.endswith("_"):
                group = group[:-1]
            rows = group.split("_")
            if len(rows) > len(tmp_result):
                tmp_result = rows
        
        res = []
        for row in tmp_result:
            seq = []
            for x in row.split(","):
                card_list.remove(int(x))
                seq.append(int(x))
            res.append(seq)
        self._res = []
        return res, card_list
    
    def count_group(self, all_card, card, jiang=''):
        n = 0
        res = []
        card_list = self.trans_card(all_card)
        if jiang:
            if card_list.count(jiang) != 2:
                return 0, [], [], [], [], '', []
            card_list.remove(jiang)
            card_list.remove(jiang)
            n += 1
            #jiang = [jiang]
        else:
            #jiang = []
            jiang = ''
        bomb = []
        triple = []
        pair = []
        seq = []
        left_card = []
        card_list.sort()
        for c in set(card_list):
            c_cnt = card_list.count(c)
            if c_cnt == 4:
                bomb.append(c)
                n += 1
                card_list.remove(c)
                card_list.remove(c)
                card_list.remove(c)
                card_list.remove(c)
            elif c_cnt == 3:
                triple.append(c)
                n += 1
                card_list.remove(c)
                card_list.remove(c)
                card_list.remove(c)
        self.card_group(card_list)
        seq, left_card = self.card_group_res(card_list)
        n += len(seq)
        return n, bomb, triple, pair, seq, jiang, left_card
    
    def count_huxi(self, uid):
        '''只计算桌面上吃碰偎牌跑牌的胡息'''
        player = Player(uid, self.bid, self.rid)
        bind = player.bind.members
        run = player.run.members  
        nestle = player.nestle.members
        pair = player.pair.members
        eat = player.eat.members
        eat_data = []
        try:
            for ec in eat:
                cc = [int(x) for x in ec.split(",")]
                cc.sort()
                eat_data.append(cc)
        except:
            eat_data = []
        return self.cal_huxi(bind, run, nestle, pair, eat_data)
        
    def cal_huxi(self, bind=[], run=[], nestle=[], pair=[], eat_data=[], bomb=[], triple=[], seq=[]):
        '''计算胡息'''
        logging.info(u"计算胡息:bind:%s,run:%s,nestle:%s,pair:%s,eat:%s,bomb:%s,triple:%s,seq:%s" % (str(bind), str(run), str(nestle), str(pair), str(eat_data), str(bomb), str(triple), str(seq)  ))
        win_score = 0
        for c in bind:
            if int(c) < 200:
                win_score += 9
            else:
                win_score += 12
        for c in run:
            if int(c) < 200:
                win_score += 6
            else:
                win_score += 9
        for c in pair:
            if int(c) < 200:
                win_score += 1
            else:
                win_score += 3
        for c in nestle:
            if int(c) < 200:
                win_score += 3
            else:
                win_score += 6
        for ec in eat_data:
            if isinstance(ec, list):
                cc = [int(x) for x in ec]
            else:
                cc = [int(x) for x in ec.split(",")] 
            cc.sort()
            if cc in [[101,102,103], [102,107,110]]:
                win_score += 3
            elif cc in [[201,202,203], [202,207,210]]:
                win_score += 6
                
        for c in bomb:
            if int(c) < 200:
                win_score += 9
            else:
                win_score += 12
        for c in triple:
            if int(c) < 200:
                win_score += 3
            else:
                win_score += 6
        for eq in seq:
            if isinstance(eq, list):
                cc = [int(x) for x in eq]
            else:
                cc = [int(x) for x in str(eq).split(",")] 
            cc.sort()
            if cc in [[101,102,103], [102,107,110]]:
                win_score += 3
            elif cc in [[201,202,203], [202,207,210]]:
                win_score += 6
                
        return win_score
    
    def check_ting(self, player, card, win_type="", put_card=""):
        if player.score['flag'] == 'n':
            logging.info(u"跑胡子%s用户%s违规不能胡牌" % (self.rid, player.uid))
            return False
        win_score = 0
        n = 0
        dark_bar = player.bind.members
        white_bar = player.run.members
        pair = player.pair.members
        nestle = player.nestle.members
        eat = player.eat.members
        eat_data = []
        for eat_card in eat:
            ec = eat_card.split(",")
            ec.sort()
            eat_data.append([int(x.strip()) for x in ec])
            
        n += len(dark_bar)
        n += len(white_bar)
        n += len(nestle)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        if put_card:
            current_card.remove(put_card)
        bomb = self.get_bomb(current_card)
        #card_nestle = self.get_nestle(current_card)
        all_card = []
        all_card.extend(current_card)
        if card:
            all_card.append(card)
        
        if len(dark_bar)+len(white_bar)+len(bomb) >= 1:
            jiang_list = self.get_jiang(all_card, card)
            if not jiang_list:
                return False
            for jiang in jiang_list:
                logging.info(u"跑胡子%s检查%s胡牌可能性:当将为%s时, card:%s" %(self.rid, player.uid, jiang, card))
                group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(all_card, card, jiang)
                if card and win_type != "win":
                    for tp in set(triple):
                        if str(tp) == str(card):
                            triple.remove(tp)
                            pair.append(tp)
                        
                logging.info(u"跑胡子%s检查%s胡牌可能性:group_n:%s, n:%s, left_card:%s" %(self.rid, player.uid, group_n, n,str(left_card)))
                #pair.extend(pair_card)
                if not left_card and group_n + n >= 7:
                    if group_n + n >= 7:
                        logging.info(u"跑胡子%s检查%s牌型合法:group_n:%s, jiang:%s" %(self.rid, player.uid, group_n, jiang))
                        win_score = self.cal_huxi(dark_bar, white_bar, nestle, pair, eat_data, bomb_card, triple, seq)
                        logging.info(u"跑胡子%s检查%s牌型合法:group_n:%s, jiang:%s, score:%s" %(self.rid, player.uid, group_n, jiang, win_score))
                        if win_score >= 15:
                            return True
        else:
            group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(all_card, card, '')
            if card and win_type != "win":
                for tp in set(triple):
                    if str(tp) == str(card):
                        triple.remove(tp)
                        pair.append(tp)
            #pair.extend(pair_card)
            if group_n + n >= 7:
                win_score = self.cal_huxi(dark_bar, white_bar, nestle, pair, eat_data, bomb_card, triple, seq)
                if win_score >= 15:
                    return True
        return False
    
    def check_win(self, player, card, win_type=""):
        if player.score['flag'] == 'n':
            logging.info(u"跑胡子%s用户%s违规不能胡牌" % (self.rid, player.uid))
            return False, [], [], [], '', []
        win_score = 0
        n = 0
        dark_bar = player.bind.members
        white_bar = player.run.members
        pair = player.pair.members
        nestle = player.nestle.members
        eat = player.eat.members
        eat_data = []
        for eat_card in eat:
            ec = eat_card.split(",")
            ec.sort()
            eat_data.append([int(x.strip()) for x in ec])
            
        n += len(dark_bar)
        n += len(white_bar)
        n += len(nestle)
        n += len(pair)
        n += len(eat)
        current_card = player.current_card.members
        bomb = self.get_bomb(current_card)
        #card_nestle = self.get_nestle(current_card)
        all_card = []
        all_card.extend(current_card)
        if card:
            all_card.append(card)
        
        if len(dark_bar)+len(white_bar)+len(bomb) >= 1:
            jiang_list = self.get_jiang(all_card, card)
            if not jiang_list:
                return False, [], [], [], '', []
            for jiang in jiang_list:
                logging.info(u"跑胡子%s检查%s胡牌可能性:当将为%s时, card:%s" %(self.rid, player.uid, jiang, card))
                group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(all_card, card, jiang)
                if card and win_type != "win":
                    for tp in set(triple):
                        if str(tp) == str(card):
                            triple.remove(tp)
                            pair_card.append(tp)
                logging.info(u"跑胡子%s检查%s胡牌可能性:group_n:%s,has_n:%s,left_card:%s, bomb:%s,triple:%s,pair:%s,seq:%s,jiang:%s" %(self.rid, player.uid, group_n, n,str(left_card), str(bomb_card), str(triple), str(pair_card), str(seq), jiang))
                pair.extend(pair_card)
                if not left_card and group_n + n >= 7:
                    if group_n + n >= 7:
                        logging.info(u"跑胡子%s检查%s牌型合法:group_n:%s, jiang:%s" %(self.rid, player.uid, group_n, jiang))
                        win_score = self.cal_huxi(dark_bar, white_bar, nestle, pair, eat_data, bomb_card, triple, seq)
                        logging.info(u"跑胡子%s检查%s牌型合法:group_n:%s, jiang:%s, score:%s" %(self.rid, player.uid, group_n, jiang, win_score))
                        if win_score >= 15:
                            return win_score, bomb_card, triple, seq, jiang_pai, left_card
        else:
            group_n, bomb_card, triple, pair_card, seq, jiang_pai, left_card = self.count_group(all_card, card, '')
            if card and win_type != "win":
                for tp in set(triple):
                    if str(tp) == str(card):
                        triple.remove(tp)
                        pair_card.append(tp)
            pair.extend(pair_card)
            logging.info(u"跑胡子%s检查%s胡牌可能性:group_n:%s,has_n:%s,left_card:%s, bomb:%s,triple:%s,pair:%s,seq:%s" %(self.rid, player.uid, group_n, n,str(left_card), str(bomb_card), str(triple), str(pair_card), str(seq)))
            if not left_card and group_n + n >= 7:
                win_score = self.cal_huxi(dark_bar, white_bar, nestle, pair, eat_data, bomb_card, triple, seq)
                if win_score >= 15:
                    return win_score, bomb_card, triple, seq, jiang_pai, left_card
        return False, [], [], [], '', []

    def start(self):
        self.room['status'] = 'start'
        game_round = int(self.room['game_round'])
        all_card = []
        for i in range(2):
            for j in (1, 2):
                for k in (1,2,3,4,5,6,7,8,9,10):
                    all_card.append(j*100+k)
                    all_card.append(j*100+k)
                    
        init_left_card = 19
        random.shuffle(all_card)
        random.shuffle(all_card)
        members = self.members
        player_cnt = len(members)
        dealer = self.room['dealer']
        dealer_seat = self.members.index(dealer)
        dealer_card = ''
        for i in range(player_cnt):
            idex = (dealer_seat + i) % player_cnt
            uid = self.members[idex]
            player = Player(uid, self.bid, self.rid, True)
            card = []
            if i == 0:
                for j in range(21):
                    card.append(all_card.pop())
                dealer_card = card[-1]
                #self.room['last_card'] = dealer_card
            else:
                for j in range(20):
                    card.append(all_card.pop())
            card.sort()
            player.current_card.extend(card)
            mid = self.incr_mid()
            card, lock_card = self.card_sort(card)
            nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"lock_card":lock_card, "dealer_card":dealer_card,"left_card":init_left_card, "rid":self.rid, "mid":mid, "act":"game_start", "dealer":self.room['dealer'], "card":card, "game_round":self.room['game_round'], "all_round":self.room['all_round']}})
        self.room['last_get_user'] = dealer
        self.room['last_card_type'] = ""
        self.room['last_card'] = ""
        self.current_card.clear()
        self.current_card.extend(all_card)
        logging.info(u"跑胡子房间rid:%s,game_round:%s,发牌结束: %s" % (self.rid, self.room['game_round'], str(self.current_card.members)))
        p_dealer = Player(dealer, self.bid, self.rid)
        win_flag = self.check_win(p_dealer, '', "win")
        if win_flag[0]:
            self.tips_act.append("win")
            self.tips_user.append(dealer)
            #mid = self.incr_mid()
            tips = ['win']
            card = ""
            nsq_pub({"b":self.bid, "u":str(dealer), "t":"game", "d":{"act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
        else:
            self.notify_put(dealer)
        
    def notify_put(self, uid):
        '''通知玩家出牌'''
        self.room['turn_put'] = uid
        self.room['last_put_user'] = ""
        #mid = self.incr_mid()
        
        all_nestle = []
        for member in self.members:
            if member != uid:
                member_player = Player(member, self.bid, self.rid)
                nestle = member_player.nestle.members
                if nestle:
                    all_nestle.extend(nestle)
        
        disable_card = []
        if all_nestle:
            p = Player(uid, self.bid, self.rid)
            current_card = p.current_card.members
            for put_card in all_nestle:
                if current_card.count(put_card) == 1:
                    win_flag = False
                    all_card = [] 
                    all_card.extend(range(101, 111))
                    all_card.extend(range(201, 211))
                    for card in all_card:
                        if self.check_ting(p, str(card), "", put_card):
                            win_flag = True
                            break
                    if not win_flag:
                        disable_card.append(str(put_card))
            
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"turn_put", "rid":self.rid, "uid":uid, "disable_card":disable_card}})
    
    def tips_huxi(self, uid, huxi):
        '''通知玩家胡息变化'''
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"act":"tips_huxi", "huxi":huxi, "rid":self.rid, "uid":uid}})
    
    
    def next_pop(self, uid=None, from_bar=False, repeat=False):
        # 发牌逻辑
        if not uid:
            last_get_user = self.room['last_get_user']
            logging.info("next_pop, last:%s" % last_get_user)
            last_player_seat = self.members.index(str(last_get_user))
            idx = (last_player_seat + 1) % len(self.members)
            uid = self.members[idx]
        card = self.current_card.pop()
        if not card:
            logging.info("over===========")
            self.game_over()
            return
        #每次发牌都将上一次的提示用户和提示类型清空
        self.tips_act.clear()
        self.tips_user.clear()
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.room['turn_put'] = ""
        self.room['last_put_user'] = ""
        self.room['last_get_user'] = uid
        self.room['last_card'] = card
        self.room['last_card_type'] = "get"
        left_card = len(self.current_card)
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"left_card":left_card, "mid":mid, "uid":uid, "act":"get_card", "card":card, "tips":[], "rid":self.rid}})
        time.sleep(1)
        #发完牌后检查当前玩家是否胡牌, 跑牌等
        p = Player(uid, self.bid, self.rid)
        win_flag = self.check_win(p, card, "win")
        if win_flag[0]:
            logging.info(u"跑胡子房间%s,墩上摸牌:%s,玩家%s推送胡提示" % (self.rid, card, uid))
            self.tips_user.append(uid)
            self.tips_act.append("win")
            p.tips.append("win")
            p.score['win_from'] = 'get_card'
            self.room['stop_pop_user'] = ""
            self.room['stop_pop_act'] = ""
            tips = ['win']
            nsq_pub({"b":self.bid, "u":uid, "t":"game", "d":{"act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
            return
        self.next_pop_check()
            
    def next_pop_check(self):
        # 发牌逻辑
        uid = self.room['last_get_user']
        card = self.room['last_card']
        player_cnt = len(self.members)
        user_seat = self.members.index(uid)
        members = []
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            members.append(self.members[idex])
        
        p = Player(uid, self.bid, self.rid)
        tips = []
        current_card = p.current_card.members
        #检查该牌是否可以提
        bind_type = ''
        if self.check_bind(current_card, card):
            bind_type = "bind"
            p.current_card.remove(card, 3)
        elif card in p.nestle.members:
            bind_type = "nestle"
            p.nestle.remove(card, 3)
        
        if bind_type:
            p.bind.append(card)
            mid = self.incr_mid()
            card_list = [card] * 4
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"bind", "bind_type":bind_type, "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid}})
            huxi = self.count_huxi(uid)
            if huxi:
                p.score['huxi'] = huxi
                self.tips_huxi(uid, huxi)
                
            logging.info(u"玩家%s摸牌:%s, 自动提牌" % (uid, card))
            win_flag = self.check_win(p, '', 'win')
            if win_flag[0]:
                p.score['win_from'] = "bind"
                logging.info(u"跑胡子房间%s,墩上摸牌:%s,玩家bind提牌后%s推送胡提示" % (self.rid, card, uid))
                self.do_win(uid, '', 'win', win_flag)
                
                return
            
            bomb = self.get_bomb(p.current_card.members)
            if len(p.bind.members)+len(p.run.members)+len(bomb) > 1:
                #重跑直接下家发牌
                logging.info(u"跑胡子%s用户%s自动提牌:%s,>1 不用出牌, 发下一家" % (self.rid, uid, card))
                self.next_pop()
            else:
                logging.info(u"跑胡子%s用户%s自动提牌:%s,<=1 需要出牌" % (self.rid, uid, card))
                self.notify_put(uid)
            return
            
        #检查该牌是否可以跑
        if card in p.pair.members:
            run_type = 'pair'
            p.pair.remove(card)
            p.run.append(card)
            mid = self.incr_mid()
            card_list = [card] * 4
            logging.info(u"玩家%s摸牌:%s, 自动跑" % (uid, card))
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"run", "run_type":run_type, "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid}})
            huxi = self.count_huxi(uid)
            if huxi:
                p.score['huxi'] = huxi
                self.tips_huxi(uid, huxi)
            
            win_flag = self.check_win(p, '', 'win')
            if win_flag[0]:
                p.score['win_from'] = "run"
                logging.info(u"跑胡子房间%s,墩上摸牌:%s,玩家run跑牌后%s推送胡提示" % (self.rid, card, uid))
                self.do_win(uid, '', 'win', win_flag)
                
                #self.tips_user.append(uid)
                #self.tips_act.append("win")
                #p.tips.append("win")
                #p.score['win_from'] = 'run'
                #self.room['stop_pop_user'] = ""
                #self.room['stop_pop_act'] = ""
                #tips = ['win']
                #nsq_pub({"b":self.bid, "u":uid, "t":"game", "d":{"act":"tips", "card":card, "tips":tips, "rid":self.rid, "uid":uid}})
                return
            
            bomb = self.get_bomb(p.current_card.members)
            if len(p.bind.members)+len(p.run.members)+len(bomb) > 1:
                logging.info(u"跑胡子%s用户%s自动跑牌:%s,>1 不用出牌, 发下一家" % (self.rid, uid, card))
                self.next_pop()
            else:
                logging.info(u"跑胡子%s用户%s自动跑牌:%s,<=1 需要出牌" % (self.rid, uid, card))
                self.notify_put(uid)
            return

        #检查是否可以偎牌
        valid_num = self.valid_card_num(current_card)
        if self.check_nestle(current_card, card) and valid_num >2:
            p.nestle.append(card)
            p.current_card.remove(card, 2)
            mid = self.incr_mid()
            card_list = [card] * 3
            logging.info(u"跑胡子%s玩家%s摸牌:%s, 自动偎牌" % (self.rid, uid, card))
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"nestle", "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid}})
            huxi = self.count_huxi(uid)
            if huxi:
                p.score['huxi'] = huxi
                self.tips_huxi(uid, huxi)
            
            win_flag = self.check_win(p, '', 'win')
            if win_flag[0]:
                p.score['win_from'] = "nestle"
                logging.info(u"跑胡子房间%s,墩上摸牌:%s,玩家nestle偎牌后%s推送胡提示" % (self.rid, card, uid))
                self.do_win(uid, '', 'win', win_flag)
                return
            self.notify_put(uid)
            return

        win_user = []
        user_seat = members.index(uid)
        player_cnt = len(members)
        
        for i in range(1, player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            member_player = Player(member, self.bid, self.rid)
            card_list = member_player.current_card.members
            win_flag = self.check_win(member_player, card, 'get_win')
            if win_flag[0]:
                win_user.append(member)
                logging.info(u"玩家%s摸牌:%s, 其他玩家有胡牌" % (uid, str(win_user)))
                tips = ["win"]
                #self.room['stop_pop_act'] = "win"
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"tips", "tips":tips, "card":card, "rid":self.rid, "uid":uid}})
                
        if win_user:
            self.tips_user.extend(win_user)
            self.tips_act.append("win")
            return
        
        self.check_run_pair_eat(uid)
        
        
    def check_run_pair_eat(self, uid=''):
        #检查其他玩家是否跑牌
        members = self.members
        if not uid:
            uid = self.room['last_get_user']
        user_seat = members.index(uid)
        player_cnt = len(members)
        card = self.room['last_card']
        for i in range(1, player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            member_player = Player(member, self.bid, self.rid)
            card_list = member_player.current_card.members
            run_type = self.check_run(member_player, card)
            #检查该牌是否可以跑
            if run_type:
                if run_type == 'pair':
                    member_player.pair.remove(card)
                elif run_type == 'run':
                    member_player.current_card.remove(card, 3)
                else:
                    member_player.nestle.remove(card)
                self.room['stop_pop_user'] = ""
                self.room['stop_pop_act'] = ""
                
                member_player.run.append(card)
                mid = self.incr_mid()
                run_card = [card] * 4
                
                logging.info(u"玩家%s摸牌,其他玩家%s有自动跑牌" % (uid, member))
                for m_uid in members:
                    nsq_pub({"b":self.bid, "u":m_uid, "t":"game", "d":{"act":"run", "run_type":run_type, "mid":mid, "card_list":run_card, "card":card, "rid":self.rid, "uid":member}})
                
                huxi = self.count_huxi(member)
                if huxi:
                    member_player.score['huxi'] = huxi
                    self.tips_huxi(member, huxi)
                
                win_flag = self.check_win(member_player, '', 'get_win')
                if win_flag[0]:
                    logging.info(u"跑胡子%s玩家%s跑牌后可以胡牌" % (self.rid, uid))
                    tips = ["win"]
                    self.tips_user.append(member)
                    self.tips_act.append("win")
                    member_player.tips.append("win")
                    member_player.score['win_from'] = "run"
                    nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"tips", "tips":tips, "card":card, "rid":self.rid, "uid":uid}})
                    return
                
                self.room['last_get_user'] = member
                member_current_card = member_player.current_card.members
                bomb = self.get_bomb(member_current_card)
                if len(member_player.bind)+len(member_player.run)+len(bomb) > 1:
                    logging.info(u"跑胡子%s其他玩家摸牌,该用户%s自动跑牌:%s,>1 不用出牌, 发下一家" % (self.rid, member, card))
                    self.next_pop()
                else:
                    logging.info(u"跑胡子%s其他玩家摸牌,该用户%s自动跑牌:%s,<=1 需要出牌" % (self.rid, member, card))
                    self.notify_put(member)
                return   
        
        tips_flag = False
        #检查其他玩家吃碰
        for i in range(player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            member_player = Player(member, self.bid, self.rid)
            tips = []
            if card in member_player.bad_card:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s的臭牌" %(uid, card, member))
                continue
            elif card in member_player.out_card:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s出过的牌" %(uid, card, member))
                continue
            if member_player.score['chongzhao']:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s冲招" %(uid, card, member))
                continue
            
            card_list = member_player.current_card.members
            if self.valid_card_num(card_list) >= 3:
                if self.check_pair(card_list, card):
                    logging.info(u"玩家%s墩上摸牌:%s, 该玩家可以碰:%s" %(uid, card, member) )
                    tips.append("pair")
            eat_card = []
            need_display = "n"
            display_card = {}
            if i <= 1:
                if self.valid_card_num(card_list) >= 3:
                    c_cnt = card_list.count(card)
                    if c_cnt <= 2:
                        eat_card, display_card, need_display = self.check_eat(card_list, card)
                        if eat_card:
                            tips.append("eat")
                else:
                    logging.info(u"跑胡子%s该张是玩家%s的eat臭牌:%s" % (self.rid, member, card))
            if tips:
                tips_flag = True
                self.tips_user.append(member)
                self.tips_act.extend(tips)
                member_player.tips.extend(tips)
                logging.info(u"玩家%s墩上摸牌:%s, 该玩家需要提示:%s, %s" %(uid, card, member, str(tips)))
                #mid = self.incr_mid()
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"tips", "tips":tips, "need_display":need_display, "display_card":display_card, "eat_card":eat_card, "card":card, "rid":self.rid, "uid":uid}})
        
        if not tips_flag:
            self.discard(uid, card)
    
    def compare_seat(self, seat1, seat2, put_user_seat):
        s1 = seat1 - put_user_seat
        s2 = seat2 - put_user_seat
        if s1 == 0:
            return seat1
        elif s2 == 0:
            return seat2
        elif (s1 < 0 and s2 < 0) or (s1 > 0 and s2 > 0):
            if s1 < s2:
                return seat1
            else:
                return seat2
        else:
            if s1 < s2:
                return seat2
            else:
                return seat1
                            
    def discard(self, uid, card):
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.room['turn_put'] = ""
        self.tips_user.clear()
        p = Player(uid, self.bid, self.rid)
        p.out_card.append(card)
        logging.info(u"玩家%s墩上摸牌:%s, 作废" %(uid, card) )
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"discard", "mid":mid, "card":card, "rid":self.rid, "uid":uid}})
        self.next_pop()

    def init_bind(self):
        for member in self.members:
            member_player = Player(member, self.bid, self.rid)
            init_bind = self.get_bomb(member_player.current_card.members)
            binds = []
            for bd in init_bind:
                binds.append([bd]*4)
                member_player.current_card.remove(bd, 4)
                member_player.bind.append(bd)
            if binds:
                mid = self.incr_mid()
                for mm in self.members:
                    nsq_pub({"b":self.bid, "u":mm, "t":"game", "d":{"mid":mid, "act":"init_bind", "card_list":binds, "rid":self.rid, "uid":member}})
                huxi = self.count_huxi(member)
                if huxi:
                    member_player.score['huxi'] = huxi
                    self.tips_huxi(member, huxi)
    def put_card(self, uid, data):
        # 玩家出牌逻辑
        #是否重复发牌给客户端
        stop_pop_user = self.room['stop_pop_user']
        if stop_pop_user and stop_pop_user != str(uid):
            logging.error(u"玩家:%s有提示未处理,轮不到%s出牌" % (stop_pop_user, uid))
            return
        last_put_user = self.room['last_put_user']
        if uid == last_put_user:
            logging.error(u"玩家:%s不能连续出牌" % (uid))
            return
        card = str(data['card'])
        p = Player(uid, self.bid, self.rid)
        c_cnt = p.current_card.count(card)
        if c_cnt == 0:
            logging.error(u"出牌错误,该玩家没有该牌")
            get_last_data('', self.bid, uid, data)
            return
        if c_cnt in (3,4):
            logging.error(u"出牌错误,偎牌,提牌不能出")
            return
        self.room['turn_put'] = ''
        p.out_card.append(card)
        p.current_card.remove(card)
        
        self.out_card.append(card)
        
        self.room['last_put_user'] = uid
        self.room['last_get_user'] = uid
        self.room['last_card'] = card
        self.room['last_card_type'] = "put"
        members = self.members
        
        mid = self.incr_mid()
        for member in members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"put_card", "card":card, "tips":[], "rid":self.rid, "uid":uid}})
            
            if len(self.current_card.members) == 19:
                self.init_bind()
                    
        user_seat = members.index(uid)
        player_cnt = len(members)
        for i in range(1, player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            member_player = Player(member, self.bid, self.rid)
            card_list = member_player.current_card.members
            win_flag = self.check_win(member_player, card, 'put_win')
            if win_flag[0]:
                self.room['stop_pop_user'] = member
                self.room['stop_pop_act'] = "put_win"
                self.put_win(member, win_flag)
                return
            
        for i in range(1, player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            #logging.info(u"玩家%s出牌 检查%s要是否跑牌" % (uid, member))
            member_player = Player(member, self.bid, self.rid)
            card_list = member_player.current_card.members
            #检查该牌是否可以跑
            run_type = ''
            if self.check_bind(card_list, card):
                run_type = "run"
                member_player.current_card.remove(card, 3)
            elif card in member_player.nestle:
                run_type = "nestle"
                member_player.nestle.remove(card)
                p.score['chongzhao'] = 'y'
            if run_type:
                member_player.run.append(card)
                self.room['stop_pop_user'] = ""
                self.room['stop_pop_act'] = ""
                self.room['last_get_user'] = member
                
                mid = self.incr_mid()
                run_card = [card] * 4
                
                logging.info(u"玩家%s出牌 %s要跑牌" % (uid, member))
                for m_uid in members:
                    nsq_pub({"b":self.bid, "u":m_uid, "t":"game", "d":{"act":"run", "run_type":run_type, "card_list":run_card, "mid":mid, "card":card, "rid":self.rid, "uid":member}})
                
                huxi = self.count_huxi(member)
                if huxi:
                    p.score['huxi'] = huxi
                    self.tips_huxi(member, huxi)
                
                win_flag = self.check_win(member_player, '', 'put_win')
                if win_flag[0]:
                    self.tips_act.append("win")
                    member_player.score['win_from'] = 'run'
                    self.room['stop_pop_user'] = member
                    self.room['stop_pop_act'] = "put_win"
                    self.put_win(member, win_flag)
                    return
            
                if len(member_player.bind)+len(member_player.run) > 1:
                    self.next_pop()
                else:
                    self.notify_put(member)
                return   
            
        tips_flag = False
        for i in range(1, player_cnt):
            idex = (user_seat + i) % player_cnt
            member = members[idex]
            #logging.info(u"玩家%s出牌 检查%s要是否碰牌" % (uid, member))
            member_player = Player(member, self.bid, self.rid)
            tips = []
            if card in member_player.bad_card:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s的臭牌" %(uid, card, member))
                continue
            elif card in member_player.out_card:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s出过的牌" %(uid, card, member))
                continue
            if member_player.score['chongzhao']:
                logging.info(u"玩家%s墩上摸牌:%s, 是玩家%s冲招" %(uid, card, member))
                continue
            card_list = member_player.current_card.members
            if self.check_pair(card_list, card):
                tips.append("pair")
            eat_card = []
            need_display = "n"
            display_card = {}
            if i == 1:
                eat_card, display_card, need_display = self.check_eat(card_list, card)
                if eat_card:
                    if need_display == 'y':
                        valid_card = 6
                    else:
                        valid_card = 3
                    if self.valid_card_num(card_list) >= valid_card:
                        tips.append("eat")
            
            if tips:
                tips_flag = True
                self.tips_user.append(member)
                self.tips_act.extend(tips)
                member_player.tips.extend(tips)
                logging.info(u"玩家%s出牌  %s需要提示, %s" % (uid, member, str(tips)))
                #mid = self.incr_mid()
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"tips", "tips":tips, "need_display":need_display, "display_card":display_card, "eat_card":eat_card, "card":card, "rid":self.rid, "uid":uid}})
        
        #玩家出的牌没有人可以吃碰, 继续发牌
        if not tips_flag:
            self.discard(uid, card)
    
    def pair(self, uid, data):
        tips_user = self.tips_user.members
        if not tips_user:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            return
        elif uid not in tips_user:
            logging.error(u"玩家%s有提示, 不该%s操作" % (str(tips_user), uid))
            return
        
        #card = last_put_player.out_card.members[-1]
        card = self.room['last_card']
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        if not self.check_pair(current_card, card):
            logging.error(u"请求错误,该用户不能碰牌:%s" % card)
            return
        for user in tips_user:
            tips_player = Player(user, self.bid, self.rid)
            tips_player.tips.clear()
        self.tips_user.clear()
        self.tips_act.clear()
        last_get_user = self.room['last_get_user']
        if self.room['last_card_type'] == "put":
            last_put_user = self.room['last_put_user']
            last_put_player = Player(last_put_user, self.bid, self.rid)
            last_put_player.out_card.pop()
        p.current_card.remove(card, 2)
        p.pair.append(card)
        
        if self.room['last_card_type'] == "put":
            last_card_user = self.room['last_put_user']
        else:
            last_card_user = last_get_user
        logging.info(u"跑胡子%s玩家%s出牌%s碰牌:%s" % (self.rid, last_card_user, uid, card))
        pair_card = [card] * 3
        
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"pair", "card_list":pair_card, "card":card, "tips":[], "rid":self.rid, "uid":uid, "put_card_uid":last_get_user}})
        
        huxi = self.count_huxi(uid)
        if huxi:
            p.score['huxi'] = huxi
            self.tips_huxi(uid, huxi)
        self.room['last_get_user'] = uid
        self.room['last_card'] = ""
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        #win_flag = self.check_win(p, '', '')
        #if win_flag[0]:
        #    win_score = win_flag[0]
        #    if self.room['last_card_type'] == "put":
        #        self.put_win(uid, win_flag)
        #        return
        #    self.tips_act.append("win")
        #    self.tips_user.append(uid)
        #    p.tips.append("win")
        #    nsq_pub({"b":self.bid, "u":str(uid), "t":"game", "d":{"act":"tips", "card":card, "tips":["win"], "rid":self.rid, "uid":uid}})
        #    return
        self.notify_put(uid)

    def eat(self, uid, data):
        '''吃牌'''
        logging.info(u"跑胡子:%s玩家要吃牌:%s, %s" % (self.rid, uid, str(data)))
        tips_user = self.tips_user.members
        tips_act = self.tips_act.members
        logging.info(tips_act)
        if not tips_user or "eat" not in tips_act:
            logging.error(u"目前没有提示, 不该%s操作" % uid)
            get_last_data('', self.bid, uid, data)
            return
        elif uid not in tips_user:
            logging.error(u"房间:%s玩家%s没有操作提示不能操作" % (self.rid, uid))
            return
        
        card = self.room['last_card']
        eat_card = data['eat_card']
        logging.info(u"玩家要吃牌:%s, %s" % (uid, card))
        if not self.can_eat(eat_card, card):
            logging.error(u"跑胡子房间%s错误,该用户%s的牌%s不能吃这张牌:%s" % (self.rid, uid, str(eat_card), card))
            get_last_data('', self.bid, uid, data)
            return
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        eat_card_list, display_card, need_display = self.check_eat(current_card, card)
        if not eat_card_list:
            logging.error(u"%s请求错误,该用户%s不能吃这张牌:%s" % (self.rid, uid, card))
            get_last_data('', self.bid, uid, data)
            return
        
        
        top_tips_user = self.room['stop_pop_user']
        top_tips_act = self.room['stop_pop_act']
        
        if "pair" not in tips_act and tips_user.index(uid) == 0:
            self.do_eat(uid, card, data)
            self.tips_user.clear()
            self.tips_act.clear()
            return
        
        self.tips_user.remove(uid)
        if not top_tips_act:
            self.room['stop_pop_user'] = uid
            self.room['stop_pop_act'] = "eat"
            p.score['data'] = json_encode(data)
            if len(tips_user)-1 ==0:
                self.do_eat(uid, card, data)
                self.tips_user.clear()
                self.tips_act.clear()
                return
        else:
            if top_tips_act != "eat":
                logging.info(u"房间%s,玩家%s吃牌,没有其他玩家%s优先级高%s" % (self.rid, uid, top_tips_user, top_tips_act))
                return
            left_tips_user = self.tips_user.members
            if left_tips_user:
                logging.info(u"房间%s,等待其他玩家确认提示:%s" % (self.rid, ",".join(left_tips_user)))
                return
            last_card_type = self.room['last_card_type']
            if last_card_type == 'put':
                last_card_user = self.room['last_put_user']
            else:
                last_card_user = self.room['last_get_user']
            last_seat = self.members.index(last_card_user)
            top_user_seat = self.members.index(top_tips_user)
            user_seat = self.members.index(uid)
            eat_seat = self.compare_seat(user_seat, top_user_seat, last_seat)
            eat_user = self.members[eat_seat]
            self.do_eat(eat_user, card)
    
    def do_eat(self, eat_user, card, data={}):
        logging.info(u"执行玩家吃牌:%s, %s, data:%s" % (eat_user, card, data))
        p = Player(eat_user, self.bid, self.rid)
        if not data:
            data = json.loads(p.score['data'])
        current_card = p.current_card.members
        
        eat_card = data['eat_card']
        c1 = eat_card[0]
        c2 = eat_card[1]
        if c1 not in current_card or c2 not in current_card:
            logging.error(u"吃牌错误,该用户%s不能吃这张牌:%s" % (eat_user, card))
            return
        display_card = data.get('display_card', [])
        if not display_card:
            display_card = []
        p = Player(eat_user, self.bid, self.rid)
        last_card_type = self.room['last_card_type']
        if last_card_type == 'put':
            last_card_uid = self.room['last_put_user']
            last_card_player = Player(last_card_uid, self.bid, self.rid)
            last_card_player.out_card.pop()
        else:
            last_card_uid = self.room['last_get_user']
        
        p.current_card.remove(c1, 1)
        p.current_card.remove(c2, 1)
        eat_card_list = [c1, c2, card]
        #eat_card_list.sort()
        p.eat.append(",".join(eat_card_list))
        current_card = p.current_card.members
        if current_card.count(card) in(1, 2):
            need_display_eat = True
        else:
            need_display_eat = False
        if need_display_eat and not display_card:
            #p.score['flag'] = 'n'
            logging.info(u"跑胡子%s用户%s违规 %s, cc:%s" % (self.rid, eat_user, card, str(current_card)))
        else:
            if display_card:
                if not isinstance(display_card[0], list):
                    display_card = [display_card]
                for dc in display_card:
                    p.eat.append(",".join(dc))
                    for c in dc:
                        p.current_card.remove(c, 1)
                #else:
                #    p.eat.append(",".join(display_card))
                #    for c in display_card:
                #        p.current_card.remove(c, 1)
                            
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"eat", "card":card, "display_card":display_card, "eat_card":eat_card_list, "tips":[], "rid":self.rid, "uid":eat_user, "last_card_uid":last_card_uid}})
        
        p.tips.clear()
        huxi = self.count_huxi(eat_user)
        if huxi:
            p.score['huxi'] = huxi
            self.tips_huxi(eat_user, huxi)
        self.room['last_get_user'] = eat_user
        self.room['last_put_user'] = ""
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        self.notify_put(eat_user)

    def check_bind_run_tips(self, uid='', card=''):
        if not uid:
            uid = self.room['last_get_user']
        card = self.room['last_card']
        p = Player(uid, self.bid, self.rid)
        current_card = p.current_card.members
        members = self.members
        #检查该牌是否可以提
        if self.check_bind(current_card, card):
            p.bind.append(card)
            p.current_card.remove(card, 3)
            mid = self.incr_mid()
            card_list = [card] * 4
            
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"bind", "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid}})
            
            huxi = self.count_huxi(uid)
            if huxi:
                p.score['huxi'] = huxi
                self.tips_huxi(uid, huxi)
                
            bomb = self.get_bomb(current_card)
            
            if len(p.bind.members)+len(p.run.members)+len(bomb) > 1:
                #重跑直接下家发牌
                self.next_pop()
            else:
                self.notify_put(uid)
            return uid

        run_type = self.check_run(p, card)
        #检查该牌是否可以跑
        if run_type:
            if run_type == 'pair':
                p.pair.remove(card)
            elif run_type == 'run':
                p.current_card.remove(card, 3)
            else:
                p.nestle.remove(card)
            p.run.append(card)
            mid = self.incr_mid()
            card_list = [card] * 4
            
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"run", "run_type":run_type, "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid, "huxi":huxi}})
            
            huxi = self.count_huxi(uid)
            if huxi:
                p.score['huxi'] = huxi
                self.tips_huxi(uid, huxi)
            bomb = self.get_bomb(current_card)
            if len(p.bind.members)+len(p.run.members)+len(bomb) > 1:
                self.next_pop()
            else:
                self.notify_put(uid)
            return uid

        #检查是否可以偎牌
        if self.check_nestle(current_card, card):
            p.nestle.append(card)
            p.current_card.remove(card, 2)
            mid = self.incr_mid()
            card_list = [card] * 3
            for member in members:
                nsq_pub({"b":self.bid, "u":member, "t":"game", "d":{"act":"nestle", "mid":mid, "card_list":card_list, "card":card, "rid":self.rid, "uid":uid}})
            self.notify_put(uid)
            return uid
    
    def pass_card(self, uid, data):
        logging.info(u"跑胡子%s玩家pass:%s" % (self.rid, uid))
        tips_user = self.tips_user.members
        tips_act = self.tips_act.members
        if uid not in tips_user:
            logging.error(u"房间:%s该用户没有提示操作不能pass:%s" % (self.rid, uid))
            get_last_data('', self.bid, uid, {"rid":self.rid})
            return
        self.tips_user.remove(uid)
        
        card = self.room['last_card']
        p = Player(uid, self.bid, self.rid)
        if "pair" in self.tips_act or "eat" in self.tips_act:
            p.bad_card.append(card)
            
        top_tips_user = self.room['stop_pop_user']
        top_tips_act = self.room['stop_pop_act']
        
        if len(tips_user)-1 ==0:
            self.tips_act.clear()
            last_get_user = self.room['last_get_user']
            last_put_user = self.room['last_put_user']
            if top_tips_user:
                logging.info(u"跑胡子%s玩家%spass, 目前最高级别用户为%s, %s" % (self.rid, uid, top_tips_user, top_tips_act))
                if top_tips_act == "win":
                    if uid == last_get_user:
                        win_type = "win"
                    else:
                        win_type = "get_win"
                    self.do_win(top_tips_user, card, win_type)
                    return
                
                if last_put_user != last_get_user and last_put_user:
                    last_put_player = Player(last_put_user, self.bid, self.rid)
                    last_put_player.out_card.pop()
                
                self.do_eat(top_tips_user, card)
                return
            else:
                logging.info(u"跑胡子%s所有玩家都pass" % self.rid)
                #if "win" in top_tips_act:
                if "win" in tips_act:
                    p = Player(uid, self.bid, self.rid)
                    if p.score['win_from'] in ('bind', 'run'):
                        bomb = self.get_bomb(p.current_card.members)
                        if len(p.bind.members)+len(p.run.members)+bomb > 1:
                            self.room['last_get_user'] = uid
                            self.next_pop()
                        else:
                            self.notify_put(uid)
                        p.score['win_from'] = ''
                        return
                    
                    if uid == last_get_user:
                        logging.info(u"玩家%s自摸点pass" % (uid))
                        self.next_pop_check()
                        return
                    else:
                        self.check_run_pair_eat(last_get_user)
                        return
                else:
                    
                    if self.room['last_card_type'] != 'put':
                        last_card_uid = last_get_user
                    else:
                        last_card_uid = last_put_user
                    self.discard(last_card_uid, card)
        else:
            logging.info(u"房间:%s玩家%spass, 等待其他玩家处理:%s" % (self.rid, uid, str()))
            return
    
    def win(self, uid, data={}):
        #胡墩上上的牌
        tips_user = self.tips_user.members
        if uid not in tips_user:
            logging.error(u"请求错误,该用户不在胡牌范围:%s" % uid)
            return
        card = self.room['last_card']
        members = self.members
        self.tips_user.remove(uid)
        last_get_user = self.room['last_get_user']
        if len(tips_user)-1 != 0:
            top_tips_user = self.room['stop_pop_user']
            if not top_tips_user:
                self.room['stop_pop_user'] = uid
                self.room['stop_pop_act'] = 'win'
                return
            last_seat = members.index(last_get_user)
            user_seat = members.index(uid)
            top_user_seat = members.index(top_tips_user)
            win_seat = self.compare_seat(user_seat, top_user_seat, last_seat)
            win_user = members[win_seat]    
        else:
            win_user = uid
        if last_get_user == win_user:
            win_type = "win"
        else:
            win_type = "get_win"
        p = Player(uid, self.bid, self.rid)
        if p.score['win_from'] in ('bind', 'run', 'nestle'):
            card = ''
        win_flag = self.check_win(p, card, win_type)
        if not win_flag[0]:
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            return
        self.do_win(win_user, card, win_type, win_flag)
    
    def do_win(self, uid, card, win_type, win_flag=None):
        p = Player(uid, self.bid, self.rid)
        p.tips.clear()
        if not win_flag:
            win_flag = self.check_win(p, card, win_type)
        win_score = win_flag[0]
        jiang = win_flag[4]
        mid = self.incr_mid()
        if card:
            p.current_card.append(card)
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "win_type":win_type, "card":card, "rid":self.rid, "uid":uid}})
        self.game_over(uid, card, jiang, win_type, win_score)
        
    def put_win(self, uid, win_flag=[]):
        #点炮胡
        last_put_user = self.room['last_put_user']
        card = self.room['last_card']
        logging.info("last_put_user:%s, card:%s" % (last_put_user, card))
        #win_flag = self.check_win(p, card)
        if not win_flag[0]:
            logging.error(u"请求错误,该用户不能胡牌:%s" % card)
            return
        win_score = win_flag[0]
        jiang = win_flag[4]
        self.room['stop_pop_user'] = ""
        self.room['stop_pop_act'] = ""
        p = Player(uid, self.bid, self.rid)
        if p.score['win_from'] != 'run':
            p.current_card.append(card)
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"win", "win_type":"put_win", "card":card, "rid":self.rid, "uid":uid}})
        self.game_over(uid, card, jiang, "put_win", win_score)

    def game_over(self, winner='', card='', jiang='', win_type='', win_score=0, from_dissmiss=False):
        #每个玩家的手牌对应的类型和胡息数和名字
        #本局胡牌玩家的总胡息分数
        #名堂
        #剩余的底牌
        #winner
        time.sleep(1)
        lose_user = ""
        end_huxi = self.room['end_huxi']
        if not end_huxi:
            end_huxi = 200
        else:
            end_huxi = int(end_huxi)
        dealer = self.room['dealer']
        db = dao.Game_DB()
        if winner:
            self.room['dealer'] = winner
            p_winner = Player(winner, self.bid, self.rid)
            mingtang_list = self.get_mingtang(p_winner, card, win_score, win_type)
            mingtang_name = self.trans_mingtang(mingtang_list)
            all_score = self.count_score(win_score, mingtang_list)
            if all_score > end_huxi:
                all_score = end_huxi
            p_winner.score['score'] = int(p_winner.score['score']) + all_score
            logging.info(u"跑胡子 %s胡,胡牌类型%s, 加%s分" %(winner, win_type, all_score))
            if win_type == "put_win":
                lose_user = self.room['last_put_user']
                logging.info(u"跑胡子 %s点炮  扣%s分" %(lose_user, all_score))
                p_put_user = Player(lose_user, self.bid, self.rid)
                p_put_user.out_card.pop()
                p_put_user.score['score'] = int(p_put_user.score['score']) - all_score
                #db.update_player(self.rid, p_put_user, win_score, 0)
        else:
            all_score = 0
            mingtang_name = ""
            lose_user = ""
            if not from_dissmiss:
                p_dealer = Player(dealer, self.bid, self.rid)
                p_dealer.score['score'] = int(p_dealer.score['score']) - 10
            
        logging.info("跑胡子房间%s game over" % self.rid)
        game_round = self.room['game_round']
        if not game_round:
            game_round = 1
        else:
            game_round = int(game_round)
        player_card = []
        for member in self.members:
            player = Player(member, self.bid, self.rid)
            is_put_user = 0
            if member == winner:
                user_card = self.format_card(player, card, jiang, player.score['win_from'], win_type)
                user_win_score = all_score
                is_win = 1
                user_win_type = win_type
            else:
                user_card = self.format_card(player, '', '', '')
                user_win_score = 0
                if member == lose_user:
                    user_win_score = -all_score
                    is_put_user = 1
                is_win = 0
                user_win_type = ''
            if dealer == member:
                if not winner:
                    user_win_score = -10
                is_dealer = 'y'
            else:
                is_dealer = 'n'
            db.update_player(self.rid, member, user_win_score, 0)
            player_info = db.get_player(self.rid, member)
            if player.score['flag'] == 'n':
                user_flag = 'n'
            else: 
                user_flag =''
            user_data= {"user_flag":user_flag, "user_card":user_card, "win_score":user_win_score, "user_score":player_info['score'], "uid":member, "is_win":is_win, "win_type":win_type, "is_put_user":is_put_user}
            player_card.append(user_data)
            #player.current_card.clear()
            player.tips.clear()
            run = len(player.run.members)
            bind = len(player.bind.members)
            db.add_room_log(0, 0, self.rid, game_round, member, user_win_score, run, bind, is_dealer, is_win, is_put_user, user_win_type)
        room_over = 'n'
        if winner:
            player_info = db.get_player(self.rid, winner)
            if player_info['score'] >= 100:
                room_over = 'y'
        self.room['status'] = 'over'
        self.room['stop_pop_user'] = ''
        self.room['stop_pop_act'] = ''
        self.room['last_put_user'] = ''
        self.room['last_get_user'] = ''
        self.room['game_round'] = game_round + 1
        room_left_card = self.current_card.members
        db = dao.Game_DB()
        db.game_over(self.rid, game_round)
        mid = self.incr_mid()
        game_type = 'ldfpf'
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"game_over", "room_over":room_over, "game_type":"ldfpf", "room_left_card":room_left_card, "mingtang_name":mingtang_name, "dealer":dealer, "huxi":win_score, "win_type":win_type, "player_card":player_card, "game_round":game_round, "card":card, "rid":self.rid, "winner":winner, "lose_user":lose_user}})
            try:
                if db.has_user_stat(self.bid, member, game_type):
                    db.update_user_stat(self.bid, member, game_type, is_win)
                else:
                    db.add_user_stat(self.bid, member, game_type, is_win, 0)
            except:
                logging.error(u"跑胡子统计生涯错误:%s" % member)
        if room_over == 'y':
            self.dismiss()
    
    def round_score(self, score):
        #结束时候每个玩家分数四舍五入
        score = int(score)
        if score > 0:
            m = score % 10
            score -= m
            if m >= 5:
                score += 10
        elif score < 0:
            m = -score % 10
            score += m
            n = score / 10
            score = 10 * n
            print n
        return score
    
    def dismiss(self, act='room_over'):
        time.sleep(1)
        db = dao.Game_DB()
        db.dismiss_room(self.rid)
        user_stat = {}
        player_stat = db.phz_stat(self.rid)
        for user in player_stat:
            uid =  str(user['uid'])
            player_info = db.get_player(self.rid, uid)
            user_stat[uid] = self.round_score(player_info['score'])
            
        user_final_score = {}
        for member in self.members:
            final_score = 0
            m_score = user_stat[member]
            for mm in self.members:
                if mm != member:
                    final_score += m_score - user_stat[mm]
            user_final_score[member] = final_score
            
        for user in player_stat:
            uid =  str(user['uid'])
            player_info = db.get_player(self.rid, uid)
            user['user_score'] = player_info['score']
            user['score'] = self.round_score(player_info['score'])
            user['bind'] = int(user['bind'])
            user['run'] = int(user['run'])
            user['win_cnt'] = int(user['win_cnt'])
            user['lose_cnt'] = int(user['lose_cnt'])
            user['win_num'] = int(user['win_num'])
            user['final_score'] = user_final_score[uid]
            
        if player_stat:
            winner = player_stat[-1]['uid']
        else:
            winner = ""
        room_info = db.get_room(self.rid, self.bid)
        
        match_id = 0
        gid = room_info['gid']
        if not gid:
            gid = 0
        for ps in player_stat:
            if ps['uid'] == winner:
                is_winner = 'y'
            else:
                is_winner = 'n'
            db.add_room_stat(match_id, gid, self.rid, ps['uid'], ps['score'], is_winner)
            
        admin = str(room_info['admin'])
        mid = self.incr_mid()
        for member in self.members:
            nsq_pub({"b":self.bid, "u":str(member), "t":"game", "d":{"mid":mid, "act":"room_over", "rid":self.rid, "admin":admin, "winner":winner, "player_stat":player_stat}})
        
        if self.room['status']:
            card = room_info['card']
            db.deduct_card(self.bid, admin, card)
            nsq_pub({"act":"deduct_card", "bid":self.bid, "uid":admin, "card":card, "rid":self.rid}, "total")
            logging.info(u"房间%s解散成功,扣除房卡, bid:%s,uid:%s,card:%s" % (self.rid, self.bid, admin, card))
        else:
            logging.info(u"房间%s解散成功,游戏无需扣房卡" % self.rid)
            
        logging.info(u"跑胡子房间%s结束room_over" % self.rid)
        
        
        